home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Chatline (String.mui Subclass with History)
- ** Copyright (C) 2000 Gurer Ozen <madcat@linuxfan.com>
- **
- ** This code is free software; you can redistribute it and/or
- ** modify it under the terms of GNU General Public License.
- */
-
- #include "chatline.h"
-
- #include <stdlib.h>
- #include <string.h>
-
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <intuition/sghooks.h>
-
- static ULONG chatline_new(struct IClass *cl, Object *obj, struct opSet *msg);
- static ULONG chatline_dispose(struct IClass *cl,Object *obj,Msg msg);
- static MUI_HOOK_DECL(chatline_edit, struct SGWork *sgw, ULONG *msg);
- static void chatline_add(struct chatlinedata *data, char *text);
-
-
- MUI_DISPATCH(chatline_dispatch)
- {
- switch(msg->MethodID) {
- case OM_NEW: return(chatline_new(cl, obj, (APTR)msg));
- case OM_DISPOSE: return(chatline_dispose(cl, obj, (APTR)msg));
- case CHATLINE_ADD:
- chatline_add(INST_DATA(cl,obj), (char *)(((muimsg)msg)->arg1));
- return 0;
-
-
-
- }
- return(DoSuperMethodA(cl,obj,msg));
- }
-
-
- static ULONG chatline_new(struct IClass *cl, Object *obj, struct opSet *msg)
- {
- static struct Hook editHook = {{0,0}, &chatline_edit, NULL, NULL};
- struct chatlinedata *data;
-
- obj = (Object *)DoSuperNew(cl,obj,
- StringFrame,
- MUIA_String_EditHook, &editHook,
- TAG_MORE, msg->ops_AttrList);
-
- if(!obj) return(0);
-
- data = INST_DATA(cl,obj);
-
- data->pool = CreatePool(MEMF_PUBLIC, 1024, 900);
- if(!data->pool) {
- CoerceMethod(cl, obj, OM_DISPOSE);
- return 0;
- }
-
- editHook.h_Data = (void *)data;
-
-
- return((ULONG)obj);
- }
-
-
- MUI_HOOK_STATIC(chatline_edit, struct SGWork *sgw, ULONG *msg)
- {
- if(*msg == SGH_KEY && sgw->EditOp == EO_NOOP && sgw->IEvent->ie_Class == IECLASS_RAWKEY)
- {
- struct chatlinedata *data = hook->h_Data;
- UWORD code = sgw->IEvent->ie_Code;
- UWORD qual = sgw->IEvent->ie_Qualifier;
- int upd = 0;
-
- if(code == 0x4c && !(qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
- {
- /* up arrow */
-
- if(data->cur) {
- if(data->cur->prev) data->cur=data->cur->prev;
- }
- else
- data->cur = data->lastline;
-
- if(data->cur) upd=1;
- }
- else if(code == 0x4c && qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- {
- /* shift + up arrow */
-
- data->cur = data->lines;
- upd = 1;
- }
- else if(code == 0x4d && !(qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
- {
- /* down arrow */
-
- if(data->cur) data->cur = data->cur->next;
-
- if(data->cur) {
- upd = 1;
- } else {
- sgw->WorkBuffer[0] = '\0';
- sgw->NumChars = 0;
- sgw->BufferPos = 0;
- sgw->Actions |= SGA_REDISPLAY;
- }
- }
- else if(code == 0x4d && qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- {
- /* shift + down arrow */
-
- data->cur = NULL;
- sgw->WorkBuffer[0] = '\0';
- sgw->NumChars = 0;
- sgw->BufferPos = 0;
- sgw->Actions |= SGA_REDISPLAY;
- }
-
- if(upd) {
- strcpy(sgw->WorkBuffer, &data->cur->line[0]);
- sgw->NumChars = data->cur->len;
- sgw->BufferPos = data->cur->len;
- sgw->Actions |= SGA_REDISPLAY;
- }
- }
-
- return 0;
- }
-
-
- static ULONG chatline_dispose(struct IClass *cl,Object *obj,Msg msg)
- {
- struct chatlinedata *data = INST_DATA(cl,obj);
-
- if(data->pool) DeletePool(data->pool);
-
- return(DoSuperMethodA(cl, obj, msg));
- }
-
-
- static void chatline_add(struct chatlinedata *data, char *text)
- {
- struct chatlinestr *cl;
- int len;
-
- if(!text) return;
-
- len = strlen(text);
- cl = AllocPooled(data->pool, sizeof(struct chatlinestr) + len + 1);
- if(!cl) return;
- memset(cl, 0, sizeof(struct chatlinestr));
- cl->len = len;
- strcpy(&cl->line[0], text);
-
- if(data->lastline) {
- data->lastline->next = cl;
- cl->prev = data->lastline;
- } else {
- data->lines = cl;
- }
- data->lastline = cl;
- data->cur = NULL;
- }
-